<?php

declare(strict_types=1);

namespace App\AdminApi\Module\System\Api;

use App\AdminApi\AdminApiBasicsController;
use App\AdminApi\Module\System\Service\{ResourcesService};
use App\AdminApi\Module\System\Service\ResourcesCateService;
use App\AdminApi\Module\System\Service\ResourcesChunkService;
use App\AdminApi\Module\System\Validate\ResourcesCateValidate;
use App\Sys;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\{Controller, GetMapping, PostMapping, RequestMapping};
use Psr\Http\Message\ResponseInterface;
use Zms\AdminElementPlus\FormCreate\ElemenuForm;
use Zms\Attribute\Describe;
use Zms\Guard\Auth;
use Zms\HyperfResponse\Response;
use Zms\HyperfValidateAnnotations\Validate;
use Zms\Service\Uploader;
use Zms\Unit\Arr;
use Zms\Unit\Is;
use function Hyperf\Support\make;

#[
    Controller(prefix: "/admin-api/system-resources", server: self::SERVER),
    Auth(guard: self::GUARD, label: ['系统管理', '系统资源'], app: self::APP)
]
class ResourcesController extends AdminApiBasicsController
{

    #[Inject]
    protected ResourcesCateService $cate;

    #[Inject]
    protected ResourcesService $service;


    #[
        Describe(title: "获取上传配置"),
        GetMapping('uploader-configure'),
        Auth(label: ['获取上传配置'], relyon: ["system.resources.uploader"])
    ]
    public function uploaderConfigure(Uploader $uploader): ResponseInterface
    {
        $type = (string)$this->request->input('type');
        return Response::Api()->success(data: $uploader->getConfigure($type));
    }

    #[
        Describe(title: "资源上传接口"),
        PostMapping('uploader'),
        Auth(label: ['上传'], sign: "system.resources.uploader")
    ]
    public function uploader(Uploader $uploader, ResourcesChunkService $chunk): ResponseInterface
    {
        $type = $this->request->input('type', '');//上传类型
        $key = $this->request->input('key', '');//文件名
        $index = (int)$this->request->input('index', 1);//分片号
        $total = (int)$this->request->input('total', 1);//总片数
        if ($this->request->hasFile('file')) {
            $file = $this->request->file('file');
            if ($index === 1) {
                $uploader->checkUploadFileType($file, $type);
            }
            $resources = $uploader->storingFile($file, $type);

            if ($resources === null) return Response::Api()->error('文件上传失败');
            if ($total === 1) {//没有分片
                return Response::Api()->success(data: ['progress' => 'success', 'info' => $resources]);
            }
            if (!$chunk->record($key, $resources['path'], $index)) {
                return Response::Api()->error('分片储存失败');
            }
            if ($total === $index) {//分片完成
                $fileInfo = $chunk->mergeChunkFiles($key, $total);
                if ($fileInfo === null) {
                    return Response::Api()->error('上传失败');
                }
                return Response::Api()->success(data: ['progress' => 'success', 'info' => Arr::merge($resources, $fileInfo)]);
            } else {//分片未完成
                return Response::Api()->success(data: ['progress' => 'loading']);
            }
        }
        return Response::Api()->error('没有可上传的文件');

    }


    #[
        GetMapping('list'),
        Auth(label: ['资源库'], sign: "skip", logger: false)
    ]
    public function List(): ResponseInterface
    {
        $where = $this->request->inputs(['type', 'cate_id', 'name']);
        if (!$where['cate_id']) {
            unset($where['cate_id']);
        }
        $data = $this->service->search($where)->orderByRaw('id DESC')->paginate($this->pageSize());
        return Response::Api()->success(data: $data);
    }


    #[
        GetMapping('index'),
        Auth(sign: "data.resources.manage", view: '/system/resources/index')
    ]
    public function index(): ResponseInterface
    {
        $where = $this->request->inputs(['type', 'cate_id', 'name']);
        $data = $this->service->search($where)->orderByRaw('id DESC')->paginate($this->pageSize());
        return Response::Api()->success(data: $data);
    }


    #[
        PostMapping('remove'),
        Auth(label: ['删除资源'], sign: "system.resources.remove")
    ]
    public function remove(): ResponseInterface
    {
        $id = $this->request->input('id', '');
        if (Is::empty($id)) {
            return Response::Api()->success('没有有效的条件');
        }
        $count = $this->service->removeResources(['id' => $id]);
        return Response::Api()->success("{$count}个文件已删除");
    }


    #[
        PostMapping('move-cate'),
        Auth(label: ['移动分类'], sign: "system.resources.move-cate")
    ]
    public function moveCate(): ResponseInterface
    {
        $id = $this->request->input('id', '');
        $cate = $this->request->input('cate_id', '');
        if (Is::empty($id)) return Response::Api()->success('请选择要移动的文件');
        if (Is::empty($cate)) return Response::Api()->success('请选择要移动的分类');
        if ($this->service->search(['id' => $id])->update(['cate_id' => $cate])) {
            return Response::Api()->success("文件已移动到新的分类");
        }
        return Response::Api()->fail("分类移动失败");
    }


    #[
        PostMapping('rename'),
        Auth(label: ['修改名称'], sign: "system.resources.rename", describe: "修改资源名称"),
        Validate(rules: [
            ['id', 'required', 'error' => '数据异常,请刷新重试'],
            ['name', 'required', 'error' => '请输入新的{label}'],
            ['name', 'string', 'max' => 100]
        ], labels: ['name' => '文件名'])
    ]
    public function rename(): ResponseInterface
    {
        $data = $this->request->getParsedBody();
        if ($this->service->search(['id' => $data['id']])->update(['name' => $data['name']])) {
            return Response::Api()->success('修改成功');
        }
        return Response::Api()->fail("修改失败");
    }


    #[
        GetMapping('cate-list'),
        Describe(title: "资源分类")
    ]
    public function cateList(): ResponseInterface
    {
        $type = (string)$this->request->input('type', 'none');
        return Response::Api()->success(data: $this->cate->getResourcesCate(['type' => $type]));
    }


    #[
        RequestMapping('created-cate'),
        Auth(label: ['创建分类'], sign: "system.resources.createdCate"),
        ElemenuForm(class: ResourcesCateService::class, function: "createdResourcesCateForm", param: ["type"])
    ]
    public function createdCate(): ResponseInterface
    {
        $validate = make(ResourcesCateValidate::class)->setData($this->request->post())->setScene('created')->validate();
        if ($validate->isFail()) {
            return Response::Api()->fail($validate->firstError());
        } else {
            $data = $validate->getSafeData();
            if ($this->cate->created($data)) {
                return Response::Api()->success('分类添加成功');
            }
            return Response::Api()->fail('分类添加失败');
        }
    }

    #[
        RequestMapping('updated-cate'),
        Auth(label: ['编辑分类'], sign: "system.resources.updated-cate"),
        ElemenuForm(class: ResourcesCateService::class, function: "updatedResourcesCateForm", param: ["id"])
    ]
    public function updatedCate(): ResponseInterface
    {
        $validate = make(ResourcesCateValidate::class)->setData($this->request->post())->setScene('updated')->validate();
        if ($validate->isFail()) {
            return Response::Api()->fail($validate->firstError());
        } else {
            $data = $validate->getSafeData();
            if ($this->cate->search(['id' => $data['id']])->update($data)) {
                return Response::Api()->success('分类编辑成功');
            }
            return Response::Api()->fail('分类编辑失败');
        }
    }


    #[
        PostMapping('delete-cate'),
        Auth(label: ['删除分类'], sign: "system.resources.delete-cate")
    ]
    public function deleteCate(): ResponseInterface
    {
        $id = $this->request->input('id', '0');
        if ($this->cate->search(['id' => $id])->delete()) {
            $this->service->search(['cate_id' => $id])->update(['cate_id' => 0]);
            return Response::Api()->success('分类删除成功');
        }
        return Response::Api()->fail('分类删除失败');
    }

    #[
        PostMapping('record'),
        Auth(label: ['记录资源'], relyon: ['system.resources.uploader'])
    ]
    public function record(): ResponseInterface
    {
        $data = $this->request->input('list', []);
        if (is_array($data) && count($data) > 0) {
            foreach ($data as &$item) {
                $item['user_id'] = 0;
                $item['time'] = time();
            }
            if ($this->service->getModel()::insert($data)) {
                return Response::Api()->success('资源记录完成');
            }
            return Response::Api()->fail('没有记录成功的资源');
        }
        return Response::Api()->fail('没有可记录的资源');
    }


    #-----------------------------------------------------上传配置-----------------------------------------------------#
    #[
        GetMapping('configure'),
        Auth(label: ['后台设置'], sign: 'system.resources.configure', view: '/system/resources/configure')
    ]
    public function getConfigure(): ResponseInterface
    {
        return Response::Api()->success(
            data: $this->service->getConfigureForm('uploader', $this->request->getPathInfo(), '短信配置', '120px')
        );
    }

    #[
        PostMapping('configure'),
        Auth(label: ['后台设置'], relyon: ['system.resources.configure'])
    ]
    public function setConfigure(): ResponseInterface
    {
        $this->service->setConfigure('uploader', $this->request->post());
        Sys::cache()->clear();
        return Response::Api()->success("设置成功");
    }
}
